package com.yrc.controller;

import com.yrc.pojo.Users;
import com.yrc.pojo.bo.ShopcartBO;
import com.yrc.pojo.bo.UserBO;
import com.yrc.pojo.vo.UsersVO;
import com.yrc.service.UserService;
import com.yrc.utils.*;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.ArrayList;
import java.util.List;

/**
 * @Author: Yrc
 * @create: 2020/11/18 22:02
 */
//@Controller
@Api(value = "注册登录",tags = "用于注册登录的相关接口")
@RestController
@RequestMapping("passport")
public class PassportController extends BaseController{
    @Autowired
    private UserService userService;
    @Autowired
    private RedisOperator redisOperator;

    @ApiOperation(value = "用户名是否存在",notes = "用户名是否存在",httpMethod = "GET")
    @GetMapping("/usernameIsExist")
    public R usernameIsExist(@RequestParam String username){
        //1.判断用户名不能为空
        if(StringUtils.isBlank(username)){
            return R.errorMsg("用户名不能为空");
        }

        //2.查找用户名是否存在
        boolean isExist = userService.queryUsernameIsExist(username);
        if(isExist){
            return R.errorMsg("用户名已经存在");
        }

        //3.请求成功，用户名没有被注册
        return R.ok();
    }

    @ApiOperation(value = "用户注册",notes = "用户注册",httpMethod = "POST")
    @PostMapping("/regist")
    public R regist(@RequestBody UserBO userBO,
                    HttpServletRequest request,
                    HttpServletResponse response){
        String username = userBO.getUsername();
        String password = userBO.getPassword();
        String confirmPwd = userBO.getConfirmPassword();

        //判断用户名和密码必须不为空
        if(StringUtils.isBlank(username) ||
                StringUtils.isBlank(password) ||
                StringUtils.isBlank(confirmPwd)){
            return R.errorMsg("用户名或密码不能为空");
        }

        //查询用户名是否存在
        boolean isExist = userService.queryUsernameIsExist(username);
        if(isExist){
            return R.errorMsg("用户名已经存在");
        }

        //密码长度不能少于6位
        if(password.length() < 6){
            return R.errorMsg("密码长度不能少于6");
        }

        //判断两次密码是否一致
        if(!password.equals(confirmPwd)){
            return R.errorMsg("两次密码输入不一致");
        }

        //实现注册
        Users userResult = userService.createUser(userBO);

//        userResult = setNullProperty(userResult);

        //实现用户的redis会话
        UsersVO usersVO = conventUsersVO(userResult);

        CookieUtils.setCookie(request,response,"user",
                JsonUtils.objectToJson(usersVO),true);

        //同步购物车数据
        synchShopcartData(userResult.getId(), request, response);
        return R.ok();
    }



    @ApiOperation(value = "用户登录",notes = "用户登录",httpMethod = "POST")
    @PostMapping("/login")
    public R login(@RequestBody UserBO userBO,
                   HttpServletRequest request,
                   HttpServletResponse response) throws Exception {
        String username = userBO.getUsername();
        String password = userBO.getPassword();

        //判断用户名和密码必须不为空
        if(StringUtils.isBlank(username) ||
                StringUtils.isBlank(password)){
            return R.errorMsg("用户名或密码不能为空");
        }

        //实现登录
       Users userResult =  userService.queryUserForLogin(username,
               MD5Utils.getMD5Str(password));

        if(userResult == null){
            return R.errorMsg("用户名或密码不正确");
        }

//        userResult = setNullProperty(userResult);

        //实现用户的redis会话
        UsersVO usersVO = conventUsersVO(userResult);

        CookieUtils.setCookie(request,response,"user",
                JsonUtils.objectToJson(usersVO),true);

        //同步购物车数据
        synchShopcartData(userResult.getId(), request, response);

        return R.ok(userResult);
    }

    /**
     * 注册登录成功后，同步cookie和redis中的购物车数据
     */
    private void synchShopcartData(String userId, HttpServletRequest request,
                                   HttpServletResponse response) {

        /**
         * 1.redis中无数据，如果cookie中的购物车为空，那么这个时候不做任何处理
         *                  如果cookie中的购物车不为空，此时直接放入redis中
         * 2.redis中有数据，如果cookie中的购物车为空，那么直接把redis的购物车覆盖本地cookie
         *                  如果cookie中的购物车不为空，
         *                          如果cookie中的某个商品在redis中存在，
         *                          则以cookie为主，删除redis中的，把cookie中的商品直接覆盖redis中（参考京东）
         * 3.同步到redis中去了以后，覆盖本地cookie购物车的数据，保证本地购物车的数据是同步最新的
         *
         */

        //从redis中获取购物车
        String shopcartJsonRedis = redisOperator.get(FOODIE_SHOPCART + ":" + userId);

        //从cookie中获取购物车
        String shopcartStrCookie = CookieUtils.getCookieValue(request, FOODIE_SHOPCART, true);

        if (StringUtils.isBlank(shopcartJsonRedis)) {
            //redis为空，cookie不为空，直接把cookie中的数据放入redis
            if (StringUtils.isNotBlank(shopcartStrCookie)) {
                redisOperator.set(FOODIE_SHOPCART + ":" +userId, shopcartStrCookie);
            }
        } else {
            //redis不为空，cookie不为空，合并cookie和redis中购物车的商品数据（同一商品则覆盖redis）
            if (StringUtils.isNotBlank(shopcartStrCookie)) {

                /**
                 * 1.已经存在的，把cookie中对应的数量，覆盖redis（参考京东）
                 * 2.该项商品标记为待删除，统一放入一个待删除的List
                 * 3.从cookie中清理所有的待删除list
                 * 4.合并redis和cookie中的数据
                 * 5.更新到redis和cookie中
                 */

                List<ShopcartBO> shopcartListRedis = JsonUtils.jsonToList(shopcartJsonRedis,ShopcartBO.class);
                List<ShopcartBO> shopcartListCookie = JsonUtils.jsonToList(shopcartStrCookie,ShopcartBO.class);
                //定义一个待删除list
                List<ShopcartBO> pendingDeleteList = new ArrayList<>();

                for (ShopcartBO redisShopcart : shopcartListRedis) {
                    String redisSpecId = redisShopcart.getSpecId();

                    for (ShopcartBO cookieShopcart : shopcartListCookie) {
                        String cookieSpecId = cookieShopcart.getSpecId();

                        if (redisSpecId.equals(cookieSpecId)) {
                            //覆盖购买数量，不累加，参考京东
                            redisShopcart.setBuyCounts(cookieShopcart.getBuyCounts());
                            pendingDeleteList.add(cookieShopcart);
                        }
                    }
                }

                //从现有cookie中删除对应的覆盖过的商品数据
                shopcartListCookie.removeAll(pendingDeleteList);

                //合并两个list
                shopcartListRedis.addAll(shopcartListCookie);
                //更新到redis和cookie
                CookieUtils.setCookie(request, response, FOODIE_SHOPCART, JsonUtils.objectToJson(shopcartListRedis) ,true);
                redisOperator.set(FOODIE_SHOPCART + ":" +userId, JsonUtils.objectToJson(shopcartListRedis));
            } else {
                //redis不为空，cookie为空，直接把redis覆盖cookie
                CookieUtils.setCookie(request, response, FOODIE_SHOPCART, shopcartJsonRedis ,true);
            }
        }
    }

    private Users setNullProperty(Users userResult) {
        userResult.setPassword(null);
        userResult.setMobile(null);
        userResult.setEmail(null);
        userResult.setCreatedTime(null);
        userResult.setUpdatedTime(null);
        userResult.setBirthday(null);

        return userResult;
    }

    @ApiOperation(value = "用户退出登录",notes = "用户退出登录",httpMethod = "POST")
    @PostMapping("/logout")
    public R logout(@RequestParam String userId,
                    HttpServletRequest request,
                    HttpServletResponse response) {

        //清除用户的相关信息的cookie
        CookieUtils.deleteCookie(request,response,"user");


        //分布式会话中需要清除用户数据
        //用户退出登录，清除redis中user的会话信息
        redisOperator.del(REDIS_USER_TOKEN + ":" + userId);
        //用户退出登录，需要清空购物车
        CookieUtils.deleteCookie(request, response ,FOODIE_SHOPCART);
        return R.ok();

    }
}
